#ifndef QHEXEDITPRIVATE_H
#define QHEXEDITPRIVATE_H

#include <QKeyEvent>
#include <QScrollArea>
#include <QTimer>
#include <QUndoStack>
#include <QWidget>

#include "XByteArray.h"

class QHexEditPrivate : public QWidget {
  Q_OBJECT
 public:
  QHexEditPrivate(QScrollArea* parent);

  // properties
  void setCursorPos(int position);
  int cursorPos();
  void setOverwriteMode(bool overwriteMode);
  bool overwriteMode();
  void setWildcardEnabled(bool enabled);
  bool wildcardEnabled();
  void setKeepSize(bool enabled);
  bool keepSize();
  void setHorizontalSpacing(int x);
  int horizontalSpacing();
  void setTextColor(QColor color);
  QColor textColor();
  void setWildcardColor(QColor color);
  QColor wildcardColor();
  void setBackgroundColor(QColor color);
  QColor backgroundColor();
  void setSelectionColor(QColor color);
  QColor selectionColor();

  // data management
  void setData(const QByteArray& data, const QByteArray& mask);
  QByteArray data();
  QByteArray mask();
  void insert(int index, const QByteArray& ba, const QByteArray& mask);
  void insert(int index, char ch, char mask);
  void remove(int index, int len = 1);
  void replace(int index, char ch, char mask);
  void replace(int index, const QByteArray& ba, const QByteArray& mask);
  void replace(int pos, int len, const QByteArray& after,
               const QByteArray& mask);
  void fill(int index, const QByteArray& ba, const QByteArray& mask);
  void undo();
  void redo();

 signals:
  void currentAddressChanged(int address);
  void currentSizeChanged(int size);
  void dataChanged();
  void dataEdited();
  void overwriteModeChanged(bool state);

 protected:
  void focusInEvent(QFocusEvent* event);
  void resizeEvent(QResizeEvent* event);
  void keyPressEvent(QKeyEvent* event);
  void mouseMoveEvent(QMouseEvent* event);
  void mousePressEvent(QMouseEvent* event);

  void paintEvent(QPaintEvent* event);

  int cursorPos(QPoint pos);  // calc cursorpos from graphics position. DOES NOT
                              // STORE POSITION

  void resetSelection(int pos);  // set selectionStart && selectionEnd to pos
  void resetSelection();         // set selectionEnd to selectionStart
  void setSelection(
      int pos);  // set min (if below init) || max (if greater init)
  int getSelectionBegin();
  int getSelectionEnd();

 private slots:
  void updateCursor();

 private:
  void adjust();
  void ensureVisible();

  QScrollArea* _scrollArea;
  QTimer _cursorTimer;
  QUndoStack* _undoDataStack;
  QUndoStack* _undoMaskStack;

  XByteArray _xData;
  XByteArray _xMask;

  QColor _textColor;
  QColor _wildcardColor;
  QColor _backgroundColor;
  QColor _selectionColor;

  bool _blink;  // true: then cursor blinks
  bool _overwriteMode;
  bool _wildcardEnabled;
  bool _keepSize;

  int _charWidth, _charHeight;  // char dimensions (dpendend on font)
  int _cursorX, _cursorY;       // graphics position of the cursor
  int _cursorPosition;  // character positioin in stream (on byte ends in to
                        // steps)
  int _xPosHex;         // graphics x-position of the areas

  int _selectionBegin;  // First selected char
  int _selectionEnd;    // Last selected char
  int _selectionInit;   // That's, where we pressed the mouse button

  int _size;
  int _initSize;
  int _horizonalSpacing;
};

#endif  // QHEXEDITPRIVATE_H
